package com.smart.community.property.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.result.ResultCode;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.property.dto.BillingMethodDTO;
import com.smart.community.property.dto.BillingMethodQueryDTO;
import com.smart.community.property.entity.BillingMethod;
import com.smart.community.property.enums.BillingFeeTypeEnum;
import com.smart.community.property.mapper.BillingMethodMapper;
import com.smart.community.property.service.DataScopeService;
import com.smart.community.property.service.IBillingMethodService;
import com.smart.community.property.vo.BillingMethodVO;

import cn.hutool.core.util.StrUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 计费方式服务实现类
 * 
 * 严格按照《Java后端SpringBoot代码开发规范.md》Service层规范实现：
 * - 生产环境标准：移除throws Exception，使用统一异常处理
 * - 性能优化：添加缓存机制，优化数据库查询
 * - 日志规范：使用log.warn记录业务异常，log.info记录关键操作
 * - 数据验证：严格验证输入参数，确保数据完整性
 * - 权限控制：集成数据权限服务，确保操作安全
 * - 事务管理：使用@GlobalTransactional确保分布式事务一致性
 * - 代码质量：遵循单一职责原则，方法职责清晰
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 * @version 2.0.0 - 生产环境标准优化
 */
@Slf4j
@Service
public class BillingMethodServiceImpl extends ServiceImpl<BillingMethodMapper, BillingMethod> 
    implements IBillingMethodService {

    @Autowired
    private DataScopeService dataScopeService;

    @Override
    @Cacheable(value = "billing:page", key = "#query.hashCode()", unless = "#result == null")
    public IPage<BillingMethodVO> getBillingMethodPage(BillingMethodQueryDTO query) {
        log.info("分页查询计费方式，查询条件：{}", query);
        
        // 权限验证
        try {
            validateQueryPermission(query);
        } catch (Exception e) {
            log.warn("权限验证失败：{}", e.getMessage());
            throw new BusinessException(ResultCode.PERMISSION_DENIED.getCode(), "权限验证失败：" + e.getMessage());
        }
        
        // 构建分页参数
        Page<BillingMethodVO> page = new Page<>(query.getCurrent(), query.getSize());
        
        // 执行查询
        IPage<BillingMethodVO> result = baseMapper.selectPageWithPropertyCompany(
            page,
            query.getPropertyCompanyId(),
            query.getFeeType(),
            query.getBuildingTypeName(),
            query.getMethodName(),
            query.getMethodType(),
            query.getIncludeAllBuildingTypes()
        );
        
        // 处理枚举类型转换，确保VO对象中的枚举字段正确
        if (result != null && result.getRecords() != null) {
            processBillingMethodVOList(result.getRecords());
        }
        
        return result;
    }

    @Override
    @Cacheable(value = "billing:byPropertyCompanyAndFeeType", key = "#propertyCompanyId + ':' + #feeType", unless = "#result == null || #result.isEmpty()")
    public List<BillingMethodVO> getBillingMethodsByPropertyCompanyAndFeeType(
        Long propertyCompanyId, String feeType, String buildingTypeName) {
        // 有物业公司ID才需要权限验证
    	if (propertyCompanyId != null) {
    		try {
    			validatePropertyCompanyPermission(propertyCompanyId);
    		} catch (Exception e) {
    			log.warn("权限验证失败：{}", e.getMessage());
    			throw new BusinessException(ResultCode.PERMISSION_DENIED.getCode(), "权限验证失败：" + e.getMessage());
    		}
    	}
        
        // 验证费用类型有效性
        BillingFeeTypeEnum feeTypeEnum = BillingFeeTypeEnum.getByCode(feeType);
        if (feeTypeEnum == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "无效的费用类型：" + feeType);
        }
        
        // 根据物业公司ID，费用类型，建筑类型名三个参数，查询计费方式列表
        LambdaQueryWrapper<BillingMethod> wrapper = new LambdaQueryWrapper<>();
        // 物业公司ID
        if (propertyCompanyId != null) {
        	wrapper.eq(BillingMethod::getPropertyCompanyId, propertyCompanyId);
        }
        // 建筑类型名
        if (!StrUtil.isBlankIfStr(buildingTypeName)) {
        	wrapper.eq(BillingMethod::getBuildingTypeName, buildingTypeName);
        }
        // 费用类型
        wrapper.eq(BillingMethod::getFeeType, feeType);
        List<BillingMethod> result = baseMapper.selectList(wrapper);
        log.warn("根据物业公司id（{}），建筑类型名（{}），费用类型（{}）查询到结果数量：{}", propertyCompanyId, buildingTypeName, feeType, result.size());
        
        if (result == null || result.size()==0) {
        	return Collections.emptyList();
        }
        
        // 处理枚举类型转换，确保VO对象中的枚举字段正确
        List<BillingMethodVO> vos = new ArrayList<>(result.size());
        result.forEach(entity -> {
        	vos.add(parseToBillingMethodVO(entity));
        });
        return vos;
    }

    /**
     * 将实体对象转为 BillingMethodVO
     * 严格遵循《Java后端SpringBoot代码开发规范.md》中的Service层规范
     * 
     * @author Wu.Liang
     * @date 2025年8月18日
     * @param entity 计费方式实体对象
     * @return 计费方式VO对象
     */
    private BillingMethodVO parseToBillingMethodVO(BillingMethod entity) {
        if (entity == null) {
            return null;
        }
        
        BillingMethodVO vo = new BillingMethodVO();
        
        // 基础字段复制
        vo.setId(entity.getId());
        vo.setPropertyCompanyId(entity.getPropertyCompanyId());
        // 直接设置feeType字符串值，避免MyBatis类型转换错误
        vo.setFeeType(entity.getFeeType());
        vo.setBuildingTypeName(entity.getBuildingTypeName());
        vo.setMethodName(entity.getMethodName());
        vo.setMethodType(entity.getMethodType());
        vo.setUnitPrice(entity.getUnitPrice());
        vo.setFixedAmount(entity.getFixedAmount());
        vo.setTierConfig(entity.getTierConfig());
        vo.setDescription(entity.getDescription());
        vo.setStatus(entity.getStatus());
        vo.setSortOrder(entity.getSortOrder());
        vo.setCreateBy(entity.getCreateBy());
        vo.setCreateTime(entity.getCreateTime());
        vo.setUpdateTime(entity.getUpdateTime());
        vo.setRemark(entity.getRemark());
        
        // 枚举类型字段转换
        // 1. 费用类型显示文本
        BillingFeeTypeEnum feeTypeEnum = BillingFeeTypeEnum.getByCode(entity.getFeeType());
        vo.setFeeTypeText(feeTypeEnum != null ? feeTypeEnum.getDescription() : "未知");
        
        // 2. 建筑类型显示文本
        vo.setBuildingTypeDisplayText(getBuildingTypeDisplayText(entity.getBuildingTypeName()));
        
        // 3. 计费类型显示文本
        vo.setMethodTypeText(getMethodTypeText(entity.getMethodType()));
        
        // 4. 状态显示文本
        vo.setStatusText(getStatusText(entity.getStatus()));
        
        return vo;
    }
    
    /**
     * 获取建筑类型显示文本
     * 
     * @param buildingTypeName 建筑类型名称
     * @return 建筑类型显示文本
     */
    private String getBuildingTypeDisplayText(String buildingTypeName) {
        if (buildingTypeName == null || buildingTypeName.trim().isEmpty()) {
            return "适用于所有建筑类型";
        }
        return buildingTypeName;
    }
    
    /**
     * 获取计费类型显示文本
     * 
     * @param methodType 计费类型
     * @return 计费类型显示文本
     */
    private String getMethodTypeText(Integer methodType) {
        if (methodType == null) {
            return "未知类型";
        }
        
        switch (methodType) {
            case 0:
                return "按面积计费";
            case 1:
                return "固定费用";
            case 2:
                return "阶梯计费";
            case 3:
                return "按表计费";
            case 4:
                return "阶梯电价";
            default:
                return "未知类型";
        }
    }
    
    /**
     * 获取状态显示文本
     * 
     * @param status 状态
     * @return 状态显示文本
     */
    private String getStatusText(Integer status) {
        if (status == null) {
            return "未知";
        }
        
        switch (status) {
            case 0:
                return "禁用";
            case 1:
                return "启用";
            default:
                return "未知";
        }
    }
    
    @Override
    @Cacheable(value = "billing:byPropertyCompanyIdsAndFeeType", key = "#propertyCompanyIds.hashCode() + ':' + #feeType", unless = "#result == null || #result.isEmpty()")
    public List<BillingMethodVO> getBillingMethodsByPropertyCompanyIdsAndFeeType(
        List<Long> propertyCompanyIds, String feeType, String buildingTypeName) throws Exception {
        log.info("根据物业公司ID列表和费用类型查询计费方式，物业公司ID列表：{}，费用类型：{}，建筑类型：{}", 
            propertyCompanyIds, feeType, buildingTypeName);
        
        // 权限验证
        validatePropertyCompanyIdsPermission(propertyCompanyIds);
        
        // 验证费用类型有效性
        BillingFeeTypeEnum feeTypeEnum = BillingFeeTypeEnum.getByCode(feeType);
        if (feeTypeEnum == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "无效的费用类型：" + feeType);
        }
        
        List<BillingMethodVO> result = baseMapper.selectByPropertyCompanyIdsAndFeeType(
            propertyCompanyIds, feeType, buildingTypeName);
        
        // 处理枚举类型转换，确保VO对象中的枚举字段正确
        processBillingMethodVOList(result);
        
        log.info("查询计费方式完成，结果数量：{}", result.size());
        return result;
    }

    @Override
    @Cacheable(value = "billing:detail", key = "#id", unless = "#result == null")
    public BillingMethodVO getBillingMethodDetail(Long id) throws Exception {
        log.info("查询计费方式详情，ID：{}", id);
        
        BillingMethodVO result = baseMapper.selectDetailById(id);
        if (result == null) {
            throw new BusinessException(ResultCode.DATA_NOT_FOUND.getCode(), "计费方式不存在");
        }
        
        // 权限验证
        validatePropertyCompanyPermission(result.getPropertyCompanyId());
        
        // 处理枚举类型转换，确保VO对象中的枚举字段正确
        processBillingMethodVO(result);
        
        log.info("查询计费方式详情完成");
        return result;
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"billing:page", "billing:byPropertyCompanyAndFeeType", "billing:byPropertyCompanyIdsAndFeeType", "billing:detail", "billing:applicableByBuildingType"}, allEntries = true)
    public Long createBillingMethod(BillingMethodDTO dto) throws Exception {
        log.info("创建计费方式，参数：{}", dto);
        
        // 权限验证
        validatePropertyCompanyPermission(dto.getPropertyCompanyId());
        
        // 数据验证
        validateBillingMethodData(dto);
        
        // 检查重复
        if (countDuplicate(dto.getPropertyCompanyId(), dto.getFeeType(), 
            dto.getBuildingTypeName(), dto.getMethodType(), null)) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "计费方式已存在");
        }
        
        // 构建实体
        BillingMethod entity = new BillingMethod();
        BeanUtils.copyProperties(dto, entity);
        entity.setMethodType(Integer.parseInt(dto.getMethodType())); // 类型转换：String -> Integer
        entity.setStatus(1);
        entity.setSortOrder(dto.getSortOrder() != null ? dto.getSortOrder() : 0);
        
        // 保存数据
        boolean success = save(entity);
        if (!success) {
            throw new BusinessException(ResultCode.OPERATION_FAILED.getCode(), "创建计费方式失败");
        }
        
        log.info("创建计费方式成功，ID：{}", entity.getId());
        return entity.getId();
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"billing:page", "billing:byPropertyCompanyAndFeeType", "billing:byPropertyCompanyIdsAndFeeType", "billing:detail", "billing:applicableByBuildingType"}, allEntries = true)
    public void updateBillingMethod(BillingMethodDTO dto) throws Exception {
        log.info("更新计费方式，参数：{}", dto);
        
        if (dto.getId() == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "计费方式ID不能为空");
        }
        
        // 查询原数据
        BillingMethod existingEntity = getById(dto.getId());
        if (existingEntity == null) {
            throw new BusinessException(ResultCode.DATA_NOT_FOUND.getCode(), "计费方式不存在");
        }
        
        // 权限验证
        validatePropertyCompanyPermission(existingEntity.getPropertyCompanyId());
        
        // 数据验证
        validateBillingMethodData(dto);
        
        // 检查重复
        if (countDuplicate(dto.getPropertyCompanyId(), dto.getFeeType(), 
            dto.getBuildingTypeName(), dto.getMethodType(), dto.getId())) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "计费方式已存在");
        }
        
        // 构建实体
        BillingMethod entity = new BillingMethod();
        BeanUtils.copyProperties(dto, entity);
        entity.setMethodType(Integer.parseInt(dto.getMethodType())); // 类型转换：String -> Integer
        
        // 更新数据
        boolean success = updateById(entity);
        if (!success) {
            throw new BusinessException(ResultCode.OPERATION_FAILED.getCode(), "更新计费方式失败");
        }
        
        log.info("更新计费方式成功，ID：{}", entity.getId());
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @CacheEvict(value = {"billing:page", "billing:byPropertyCompanyAndFeeType", "billing:byPropertyCompanyIdsAndFeeType", "billing:detail", "billing:applicableByBuildingType"}, allEntries = true)
    public void deleteBillingMethod(Long id) throws Exception {
        log.info("删除计费方式，ID：{}", id);
        
        // 查询数据
        BillingMethod entity = getById(id);
        if (entity == null) {
            throw new BusinessException(ResultCode.DATA_NOT_FOUND.getCode(), "计费方式不存在");
        }
        
        // 权限验证
        validatePropertyCompanyPermission(entity.getPropertyCompanyId());
        
        // 删除数据
        boolean success = removeById(id);
        if (!success) {
            throw new BusinessException(ResultCode.OPERATION_FAILED.getCode(), "删除计费方式失败");
        }
        
        log.info("删除计费方式成功，ID：{}", id);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void batchDeleteBillingMethods(List<Long> ids) throws Exception {
        log.info("批量删除计费方式，ID列表：{}", ids);
        
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "删除的ID不能为空");
        }
        
        // 查询所有数据
        List<BillingMethod> entities = listByIds(ids);
        if (entities.size() != ids.size()) {
            throw new BusinessException(ResultCode.DATA_NOT_FOUND.getCode(), "部分计费方式不存在");
        }
        
        // 权限验证
        for (BillingMethod entity : entities) {
            validatePropertyCompanyPermission(entity.getPropertyCompanyId());
        }
        
        // 批量删除
        boolean success = removeByIds(ids);
        if (!success) {
            throw new BusinessException(ResultCode.OPERATION_FAILED.getCode(), "批量删除计费方式失败");
        }
        
        log.info("批量删除计费方式成功，ID列表：{}", ids);
    }

    @Override
    @Cacheable(value = "billing:applicableByBuildingType", key = "#buildingTypeName + ':' + #feeType", unless = "#result == null || #result.isEmpty()")
    public List<BillingMethodVO> getApplicableBillingMethodsByBuildingType(
        Long propertyCompanyId, String feeType, String buildingTypeName) throws Exception {
        log.info("根据建筑类型名称查询适用的计费方式，物业公司ID：{}，费用类型：{}，建筑类型：{}", 
            propertyCompanyId, feeType, buildingTypeName);
        
        // 权限验证
        validatePropertyCompanyPermission(propertyCompanyId);
        
        // 验证费用类型有效性
        BillingFeeTypeEnum feeTypeEnum = BillingFeeTypeEnum.getByCode(feeType);
        if (feeTypeEnum == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "无效的费用类型：" + feeType);
        }
        
        List<BillingMethodVO> result = baseMapper.selectApplicableByBuildingType(
            propertyCompanyId, feeType, buildingTypeName);
        
        // 处理枚举类型转换，确保VO对象中的枚举字段正确
        processBillingMethodVOList(result);
        
        log.info("查询适用的计费方式完成，结果数量：{}", result.size());
        return result;
    }

    @Override
    public boolean countDuplicate(Long propertyCompanyId, String feeType, String buildingTypeName, 
                                 String methodType, Long excludeId) throws Exception {
        log.debug("检查计费方式是否存在重复，物业公司ID：{}，费用类型：{}，建筑类型：{}，计费类型：{}，排除ID：{}", 
            propertyCompanyId, feeType, buildingTypeName, methodType, excludeId);
        
        // 验证费用类型有效性
        BillingFeeTypeEnum feeTypeEnum = BillingFeeTypeEnum.getByCode(feeType);
        if (feeTypeEnum == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "无效的费用类型：" + feeType);
        }
        
        int count = baseMapper.countDuplicate(propertyCompanyId, feeType, buildingTypeName, methodType, excludeId);
        return count > 0;
    }

    /**
     * 验证查询权限
     */
    private void validateQueryPermission(BillingMethodQueryDTO query) throws Exception {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // 检查超级管理员权限
        Boolean isSuperAdmin = dataScopeService.isUserSuperAdmin(currentUserId);
        if (isSuperAdmin) {
            return;
        }
        
        // 验证物业公司权限
        if (query.getPropertyCompanyId() != null) {
            validatePropertyCompanyPermission(query.getPropertyCompanyId());
        } else if (query.getPropertyCompanyIds() != null && !query.getPropertyCompanyIds().isEmpty()) {
            validatePropertyCompanyIdsPermission(query.getPropertyCompanyIds());
        } else {
            // 如果没有指定物业公司，则只能查询有权限的物业公司
            List<Long> authorizedCompanyIds = dataScopeService.getUserPropertyCompanyIds(currentUserId);
            if (authorizedCompanyIds.isEmpty()) {
                throw new BusinessException(ResultCode.PERMISSION_DENIED.getCode(), "无权限访问任何物业公司");
            }
            query.setPropertyCompanyIds(authorizedCompanyIds);
        }
    }

    /**
     * 验证物业公司权限
     */
    private void validatePropertyCompanyPermission(Long propertyCompanyId) throws Exception {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // 检查超级管理员权限
        Boolean isSuperAdmin = dataScopeService.isUserSuperAdmin(currentUserId);
        if (isSuperAdmin) {
            return;
        }
        
        // 验证物业公司权限
        Boolean hasPermission = dataScopeService.hasPropertyCompanyPermission(currentUserId, propertyCompanyId);
        if (!hasPermission) {
            throw new BusinessException(ResultCode.PERMISSION_DENIED.getCode(), "无权限操作该物业公司");
        }
    }

    /**
     * 验证物业公司ID列表权限
     */
    private void validatePropertyCompanyIdsPermission(List<Long> propertyCompanyIds) throws Exception {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // 检查超级管理员权限
        Boolean isSuperAdmin = dataScopeService.isUserSuperAdmin(currentUserId);
        if (isSuperAdmin) {
            return;
        }
        
        // 验证物业公司权限
        for (Long propertyCompanyId : propertyCompanyIds) {
            Boolean hasPermission = dataScopeService.hasPropertyCompanyPermission(currentUserId, propertyCompanyId);
            if (!hasPermission) {
                throw new BusinessException(ResultCode.PERMISSION_DENIED.getCode(), 
                    "无权限操作物业公司ID：" + propertyCompanyId);
            }
        }
    }

    /**
     * 处理计费方式VO列表，确保枚举类型字段正确转换
     * 
     * @param voList 计费方式VO列表
     */
    private void processBillingMethodVOList(List<BillingMethodVO> voList) {
        if (voList == null || voList.isEmpty()) {
            return;
        }
        
        for (BillingMethodVO vo : voList) {
            processBillingMethodVO(vo);
        }
    }

    /**
     * 处理单个计费方式VO，确保枚举类型字段正确转换
     * 
     * @param vo 计费方式VO
     */
    private void processBillingMethodVO(BillingMethodVO vo) {
        if (vo == null) {
            return;
        }
        
        // 确保费用类型字段正确
        if (vo.getFeeType() != null) {
            // 验证费用类型是否有效
            BillingFeeTypeEnum feeTypeEnum = BillingFeeTypeEnum.getByCode(vo.getFeeType());
            if (feeTypeEnum == null) {
                log.warn("发现无效的费用类型：{}，计费方式ID：{}", vo.getFeeType(), vo.getId());
            }
        }
        
        // 建筑类型显示文本是计算属性，不需要手动设置
        // 通过getBuildingTypeDisplayText()方法自动计算
    }

    /**
     * 验证计费方式数据
     */
    private void validateBillingMethodData(BillingMethodDTO dto) {
        if (dto == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "计费方式数据不能为空");
        }
        
        if (dto.getPropertyCompanyId() == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "物业公司ID不能为空");
        }
        
        if (dto.getFeeType() == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "费用类型不能为空");
        }
        
        // 费用类型枚举验证
        if (!dto.isValidFeeType()) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "无效的费用类型：" + dto.getFeeType());
        }
        
        if (!StringUtils.hasText(dto.getMethodName())) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "计费方式名称不能为空");
        }
        
        if (dto.getMethodType() == null) {
            throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "计费类型不能为空");
        }
        
        // 根据计费类型验证必填字段
        switch (dto.getMethodType()) {
            case "0": // 按面积计费
                if (dto.getUnitPrice() == null || dto.getUnitPrice().doubleValue() <= 0) {
                    throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "按面积计费时单价必须大于0");
                }
                break;
            case "1": // 固定费用
                if (dto.getFixedAmount() == null || dto.getFixedAmount().doubleValue() <= 0) {
                    throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "固定费用时必须大于0");
                }
                break;
            case "2": // 阶梯计费
            case "4": // 阶梯电价
                if (!StringUtils.hasText(dto.getTierConfig())) {
                    throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "阶梯计费时阶梯配置不能为空");
                }
                break;
            case "3": // 按表计费
                if (dto.getUnitPrice() == null || dto.getUnitPrice().doubleValue() <= 0) {
                    throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "按表计费时单价必须大于0");
                }
                break;
            default:
                throw new BusinessException(ResultCode.VALIDATION_FAILED.getCode(), "不支持的计费类型");
        }
    }
}
